// --- 场景 1: 使用普通变量和函数参数 (模拟你原来的代码问题) ---

// 1. 在外层作用域声明一个变量
let myData = '初始值'

// 2. 定义一个函数，它接收一个参数，并返回一个内部函数 (闭包)
function createHandler(dataParam) {
  // 当 createHandler 被调用时，dataParam 会获得 myData 的当前值的一个副本
  // 内部函数 (闭包) 捕获的是这个局部变量 dataParam
  return function () {
    console.log('闭包内部访问 dataParam:', dataParam)
  }
}

// 3. 在某个时刻，我们用 myData 的当前值创建一个处理器
const myClickHandler = createHandler(myData) // 此时 myData 是 "初始值"，所以 dataParam 也是 "初始值"

// 4. 之后，外层的 myData 变量被重新赋值
myData = '更新后的值'

// 5. 当我们稍后调用闭包时...
myClickHandler() // 输出: "闭包内部访问 dataParam: 初始值"
// 尽管 myData 已经变成了 "更新后的值"，但闭包内部的 dataParam 仍然是 "初始值"
// 因为它捕获的是 createHandler 调用时传递给 dataParam 的那个值的副本，而不是 myData 变量本身。

console.log('--- 分割线 ---')

// --- 场景 2: 直接访问外部作用域变量 (修正后的思路) ---

// 1. 重新声明变量
myData = '初始值 v2'

// 2. 定义一个函数，它不接收参数，其返回的内部函数直接访问外部的 myData 变量
function createHandlerV2() {
  // 内部函数 (闭包) 直接捕获对外层作用域中 myData 变量的引用
  return function () {
    // 注意：这里直接使用外部的 myData 变量
    console.log('闭包内部直接访问 myData:', myData)
  }
}

// 3. 创建处理器 (此时 myData 是 "初始值 v2")
const myClickHandlerV2 = createHandlerV2()

// 4. 更新外层的 myData 变量
myData = '更新后的值 v2'

// 5. 调用闭包
myClickHandlerV2() // 输出: "闭包内部直接访问 myData: 更新后的值 v2"
// 这次，闭包内部访问的是 myData 变量本身。当 myData 被更新后，
// 闭包再次执行时就能看到最新的值。

console.log('--- 分割线 ---')

// --- 场景 3: 使用对象模拟 ref 的行为 ---

// 1. 创建一个对象来包装值 (模拟 Vue 的 ref)
const myRefLikeObject = { value: '初始值 ref' }

// 2. 定义函数，闭包捕获对这个对象的引用
function createHandlerV3() {
  // 闭包捕获的是 myRefLikeObject 这个对象的引用
  return function () {
    // 通过访问对象的 .value 属性来获取/设置值
    console.log('闭包内部访问 myRefLikeObject.value:', myRefLikeObject.value)
  }
}

// 3. 创建处理器
const myClickHandlerV3 = createHandlerV3()

// 4. 更新对象内部的值 (模拟 ref.value = newValue)
myRefLikeObject.value = '更新后的值 ref'

// 5. 调用闭包
myClickHandlerV3() // 输出: "闭包内部访问 myRefLikeObject.value: 更新后的值 ref"
// 闭包捕获的是 myRefLikeObject 对象本身。当我们修改对象的 .value 属性时，
// 闭包访问的仍然是同一个对象，所以能看到更新后的值。
